package com.nebula.salary.portal.controller.manage;

import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.nebula.salary.common.constants.Const;
import com.nebula.salary.common.constants.ReturnMessage;
import com.nebula.salary.common.exception.ErrorException;
import com.nebula.salary.common.result.ResponseCode;
import com.nebula.salary.common.result.ServerResponse;
import com.nebula.salary.common.utils.RedisUtil;
import com.nebula.salary.common.utils.RegexUtil;
import com.nebula.salary.common.utils.SecurityUtil;
import com.nebula.salary.model.dto.RoleQueryDto;
import com.nebula.salary.model.dto.UserQueryDto;
import com.nebula.salary.model.pojo.Navigation;
import com.nebula.salary.model.pojo.User;
import com.nebula.salary.model.vo.PageResult;
import com.nebula.salary.model.vo.RoleVo;
import com.nebula.salary.model.vo.UserVo;
import com.nebula.salary.portal.service.IRoleService;
import com.nebula.salary.portal.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

/**
 * 用户管理
 *
 * @author codex
 * @since 2022-03-05
 */
@RestController
@RequestMapping("/manage/user")
@Api(tags = "用户管理")
public class UserManageController {
    
    @Resource
    private IUserService userService;
    
    @Resource
    private PasswordEncoder passwordEncoder;
    
    @Resource
    private IRoleService roleService;
    
    @Resource
    private RedisUtil redisUtil;
    
    
    @ApiOperation(value = "删除用户")
    @DeleteMapping("/{userIds}")
    @Transactional(rollbackFor = Exception.class)
    public ServerResponse<String> deleteUser(@ApiParam("用户ID")
                                             @PathVariable Long[] userIds) {
        if (ArrayUtil.contains(userIds, SecurityUtil.getUserId())) {
            return ServerResponse.createByErrorMessage("当前用户不能删除");
        }
        return userService.deleteUserByIds(userIds) > 0
                ? ServerResponse.createBySuccessMessage(ReturnMessage.DELETE_SUCCESS)
                : ServerResponse.createByErrorMessage(ReturnMessage.DELETE_ERROR);
    }
    
    @ApiOperation(value = "修改用户")
    @PutMapping("/")
    @Transactional(rollbackFor = Exception.class)
    public ServerResponse<String> updateUser(@RequestBody User user) {
        
        // 验证是否有权限操作该用户
        userService.checkUserDataScope(user.getUserId());
        
        // 校验数据
        if (Strings.isNullOrEmpty(user.getRealName())) {
            throw new ErrorException(ReturnMessage.NAME_CAN_NOT_BE_EMPTY);
        }
        
        if (!Strings.isNullOrEmpty(user.getPhone()) && !RegexUtil.isPhoneLegal(user.getPhone())) {
            throw new ErrorException(ReturnMessage.ILLEGAL_PHONE);
        }
        
        // 校验手机号码是否唯一
        if (Const.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
            return ServerResponse.createByErrorMessage("修改用户'" + user.getUsername() + "'失败，手机号码已存在");
        }
        
        if (user.getAge() != null && (user.getAge() < Const.MIN_AGE || user.getAge() > Const.MAX_AGE)) {
            throw new ErrorException(ReturnMessage.ILLEGAL_AGE);
        }
        
        try {
            if (Strings.isNullOrEmpty(user.getGender())) {
                user.setGender(Const.GENDER_SECRET);
            }
    
            String key = Const.MENU_ROLE_KEY + user.getUsername() + "_" + user.getUserId();
            // 删除缓存中存储的用户菜单
            List<Navigation> cacheNav = redisUtil.getObject(key);
            if (cacheNav != null && cacheNav.size() > 0) {
                redisUtil.deleteObject(key);
            }
            
            redisUtil.deleteObject(Const.LOGIN_USER_KEY + user.getUsername() + "_" + user.getUserId());
            
            user.setUsername(null);
            userService.updateById(user);
            
            return ServerResponse.createBySuccessMessage(ReturnMessage.UPDATE_SUCCESS);
        } catch (Exception e) {
            e.printStackTrace();
            return ServerResponse.createByErrorMessage(ReturnMessage.UPDATE_ERROR);
        }
    }
    
    @ApiOperation(value = "新增用户")
    @PostMapping("/")
    @Transactional(rollbackFor = Exception.class)
    public ServerResponse<String> addUser(@RequestBody User user) {
        
        // 校验数据
        userService.checkData(user);
        
        // 校验用户名是否唯一
        if (Const.NOT_UNIQUE.equals(userService.checkUsernameUnique(user.getUsername()))) {
            return ServerResponse.createByErrorMessage("新增用户'" + user.getUsername() + "'失败，用户名已存在");
        }
        
        // 校验手机号码是否唯一
        if (Const.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
            return ServerResponse.createByErrorMessage("新增用户'" + user.getUsername() + "'失败，手机号码已存在");
        }
        
        // 新增用户
        try {
            user.setPassword(passwordEncoder.encode(user.getPassword()));
            
            if (Strings.isNullOrEmpty(user.getGender())) {
                user.setGender(Const.GENDER_SECRET);
            }
            
            userService.save(user);
            return ServerResponse.createBySuccessMessage(ReturnMessage.INSERT_SUCCESS);
        } catch (Exception e) {
            e.printStackTrace();
            return ServerResponse.createByErrorMessage(ReturnMessage.INSERT_ERROR);
        }
    }
    
    @ApiOperation(value = "验证用户名是否存在")
    @GetMapping("/{type}/{username}")
    public ServerResponse<String> checkUsername(@ApiParam(value = "类型")
                                                @PathVariable String type,
                                                @ApiParam(value = "用户名")
                                                @PathVariable String username) {
        String optionType = "add";
        if (optionType.equalsIgnoreCase(type)) {
            int count = userService.count(new QueryWrapper<User>().eq(User.USERNAME, username));
            
            if (count > 0) {
                return ServerResponse.createByErrorCodeMessage(ResponseCode.USERNAME_IS_EXIST.getCode(), ReturnMessage.USERNAME_IS_EXIST);
            }
        }
        
        return ServerResponse.createByErrorCodeMessage(ResponseCode.USERNAME_ALLOWED_TO_USE.getCode(),
                ReturnMessage.USERNAME_ALLOWED_TO_USE);
    }
    
    @ApiOperation(value = "根据用户ID获取用户信息")
    @GetMapping("/{userId}")
    public ServerResponse<UserVo> getInfoByUserId(
            @ApiParam(value = "用户ID", required = true)
            @PathVariable Long userId
    ) {
        return ServerResponse.createBySuccess(userService.getInfoByUserId(userId));
    }
    
    @ApiOperation(value = "获取所有有权的角色列表")
    @GetMapping(value = {"/per/roles", "/per/rolesAdmin/{userId}"})
    public ServerResponse<List<Map<String, Object>>> getPerRolesList(
            @ApiParam(value = "用户ID")
            @PathVariable(required = false) Long userId) {
        List<RoleVo> perRoles = roleService.getPerAllList(new RoleQueryDto());
        
        List<Map<String, Object>> resultList = Lists.newArrayList();
        
        Integer hostRoleId = 1001;
        
        perRoles.forEach(roleVo -> {
            Map<String, Object> map = Maps.newLinkedHashMap();
            if (User.isAdmin(userId)) {
                // 修改或查看超级管理员用户信息
                if (roleVo.getRoleId().equals(hostRoleId)) {
                    map.put("roleId", roleVo.getRoleId());
                    map.put("roleName", roleVo.getRoleName());
                    resultList.add(map);
                }
            } else {
                // 新增或修改非超级管理员用户信息
                if (!roleVo.getRoleId().equals(hostRoleId)) {
                    map.put("roleId", roleVo.getRoleId());
                    map.put("roleName", roleVo.getRoleName());
                    resultList.add(map);
                }
            }
        });
        
        return ServerResponse.createBySuccess(resultList);
    }
    
    @ApiOperation(value = "获取有权管理的用户列表")
    @GetMapping("/")
    public ServerResponse<PageResult> getUserList(UserQueryDto dto) {
        
        PageResult pageResult = userService.getUserList(dto);
        
        return ServerResponse.createBySuccess(pageResult);
    }
    
}
